<template>
  <el-scrollbar height="100vh">
    <div class="container">
      <el-affix :offset="1">
        <h1 class="title">带箭头的线段</h1>
      </el-affix>
      <div id="map" class="map-x" ref="mapBox"></div>
      <dl>
        <dt>带箭头的线段</dt>
        <dd>forEachSegment(callback): 遍历每条线段，调用提供的回调函数。如果回调函数返回一个真值，则函数立即返回该值。否则函数返回false</dd>
        <dd>feature.getGeometry(): 获取默认几何属性</dd>
      </dl>
      <div class="codestyle"><Code /></div>
    </div>
  </el-scrollbar>
</template>
<script>
import { toRefs, reactive, ref, onMounted } from 'vue-demi'
import Code from './code.vue'
import 'ol/ol.css'
import { Map, View } from 'ol'
import Tile from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import VectorSource from 'ol/source/Vector'
import { Vector as VectorLayer } from 'ol/layer'
import Draw from 'ol/interaction/Draw'
import { Style, Stroke, Icon } from 'ol/style'
import Point from 'ol/geom/Point'

export default {
  setup () {
    const state = reactive({
      map: ref(null),
      mapBox: ref(null),
      draw: null,
      source: new VectorSource({
        wrapX: false // 禁止横向无限重复（底图渲染的时候会横向无限重复），设置了这个属性，可以让绘制的图形不跟随底图横向无限重复
      }),
      raster: new Tile({
        source: new XYZ({
          url: 'https://api.maptiler.com/maps/basic-4326/256/{z}/{x}/{y}.png?key=B3EG5uYPUvFucEWVoCa3',
          crossOrigin: ''
        })
      })
    })

    const init = () => {
      const styleFunction = (feature) => {
        const geometry = feature.getGeometry()
        const styles = [
          new Style({
            stroke: new Stroke({
              color: '#ffcc33',
              width: 2
            })
          })
        ]

        geometry.forEachSegment((start, end) => {
          const dx = end[0] - start[0]
          const dy = end[1] - start[1]
          const rotation = Math.atan2(dy, dx)
          styles.push(new Style({
            geometry: new Point(end),
            image: new Icon({
              src: require('@/assets/arrow.png'),
              anchor: [0.75, 0.5],
              rotateWithView: true,
              rotation: -rotation
            })
          }))
        })
        return styles
      }

      const vector = new VectorLayer({
        source: state.source,
        style: styleFunction
      })

      state.map = new Map({
        target: state.mapBox,
        layers: [state.raster, vector],
        view: new View({
          center: [0, 0],
          zoom: 3
        })
      })

      state.map.addInteraction(new Draw({
        source: state.source,
        type: 'LineString'
        // freehand: true // 自由绘制
      }))
    }

    onMounted(() => {
      init()
    })

    return {
      init,
      ...toRefs(state)
    }
  },
  components: {
    Code
  }
}
</script>
<style lang="scss" scoped>
@import '../../css/main.scss';
.select {
  margin: 20px 0;
}
</style>
